/*
ONEGAME
Copyright (C) 2009  Pablo Caballero

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package one.dialog;

import java.awt.Event;
import java.util.EventListener;
import java.util.Vector;
import javax.swing.event.EventListenerList;
import javax.swing.table.AbstractTableModel;

/**
 * Default Editor Table Model
 * @author Pablo Caballero
 * @version 1.0 23-jun-2009
 */
public class DefaultEditorTableModel extends AbstractTableModel implements IEditorTableModelEventSystem {

	protected Vector<FieldEditor> fields;
	protected final static int NUM_COLUMNS = 2;
	protected javax.swing.event.EventListenerList listeners;

	DefaultEditorTableModel() {
		fields = new Vector<FieldEditor>();
		listeners = new EventListenerList();
	}

	@Override
	public boolean isCellEditable(int row, int column) {
		boolean editable;
		if (column == 1 && row < fields.size()) {
			return fields.get(row).isEditable();
		} else {
			editable = false;
		}
		return editable;
	}

	public int getRowCount() {
		return fields.size();
	}

	public int getColumnCount() {
		return NUM_COLUMNS;
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		if (rowIndex < 0 || rowIndex > fields.size() || columnIndex < 0 || columnIndex >= NUM_COLUMNS) {
			throw new IndexOutOfBoundsException();
		} else {
			if (columnIndex == 0) {
				return fields.get(rowIndex).getLabel();
			} else if (columnIndex == 1 && fields.get(rowIndex).isReadable()) {
				try {
					return fields.get(rowIndex).getValue();
				} catch (Exception ex) {
					ex.printStackTrace();
					return null;
				}
			} else {
				return null;
			}
		}
	}

	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		if (rowIndex < 0 || rowIndex > fields.size() || columnIndex < 0 || columnIndex >= NUM_COLUMNS) {
			throw new IndexOutOfBoundsException();
		} else {
			if (columnIndex == 1 && fields.get(rowIndex).isEditable()) {
				try {
					fields.get(rowIndex).setValue(aValue);
					firePropertiesChanged();
				} catch (Exception ex) {
					throw new IllegalArgumentException(ex);
				}
			} else {
				throw new IllegalArgumentException();
			}
		}
	}

	@Override
	public String getColumnName(int column) {
		return null; //No name
	}

	/**
	 * Gets the vector with the fields in the model
	 * @return the vector with the fields in the model
	 */
	public Vector<FieldEditor> getFields() {
		return fields;
	}

	/**
	 * Adds a listener
	 * @param l listener
	 */
	public void addPropertiesListener(IPropertiesDialogEventListener l) {
		listeners.add(IPropertiesDialogEventListener.class, l);
	}

	/**
	 * Removes a listener
	 * @param l listener
	 */
	public void removePropertiesListener(IPropertiesDialogEventListener l) {
		listeners.remove(IPropertiesDialogEventListener.class, l);
	}

	/**
	 * Fire the event to the listeners
	 */
	public void firePropertiesChanged() {
		Object[] pairs = listeners.getListenerList();

		Event e = null;
		for (int i = pairs.length - 2; i >= 0; i -= 2) {
			if (pairs[i] == IPropertiesDialogEventListener.class) {
				if (e == null) {
					e = new Event(this, Event.ACTION_EVENT, null);
				}
				((IPropertiesDialogEventListener) pairs[i + 1]).fieldChanged(e);
			}
		}
	}
}
